home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / corelib / ncbimsg.c < prev    next >
Text File  |  1996-07-05  |  22KB  |  870 lines

  1. /*   ncbimsg.c
  2. * ===========================================================================
  3. *
  4. *                            PUBLIC DOMAIN NOTICE
  5. *               National Center for Biotechnology Information
  6. *
  7. *  This software/database is a "United States Government Work" under the
  8. *  terms of the United States Copyright Act.  It was written as part of
  9. *  the author's official duties as a United States Government employee and
  10. *  thus cannot be copyrighted.  This software/database is freely available
  11. *  to the public for use. The National Library of Medicine and the U.S.
  12. *  Government have not placed any restriction on its use or reproduction.
  13. *
  14. *  Although all reasonable efforts have been taken to ensure the accuracy
  15. *  and reliability of the software and data, the NLM and the U.S.
  16. *  Government do not and cannot warrant the performance or results that
  17. *  may be obtained by using this software or data. The NLM and the U.S.
  18. *  Government disclaim all warranties, express or implied, including
  19. *  warranties of performance, merchantability or fitness for any particular
  20. *  purpose.
  21. *
  22. *  Please cite the author in any work or product based on this material.
  23. *
  24. * ===========================================================================
  25. *
  26. * File Name:  ncbimsg.c
  27. *
  28. * Author:  Gish, Kans, Ostell, Schuler
  29. *
  30. * Version Creation Date:   2/13/91
  31. *
  32. * $Revision: 2.19 $
  33. *
  34. * File Description:
  35. *       user alert and error messages
  36. *
  37. * Modifications:
  38. * --------------------------------------------------------------------------
  39. * Date     Name        Description of modification
  40. * -------  ----------  -----------------------------------------------------
  41. * 2/13/91  Kans        Now only used for non-Vibrant versions
  42. * 09-19-91 Schuler     Added LIBCALL to Nlm_Beep()
  43. * 09-20-91 Schuler     Include <conio.h> for getche() prototype
  44. * 04-15-93 Schuler     Changed _cdecl to LIBCALL
  45. * 05-28-93 Schuler     New function: SetMonitorHook()
  46. * 06-06-93 Schuler     Added code to set/check magic_value for Monitors
  47. * 01-13-94 Schuler     Converted ErrPost to ErrPostEx
  48. * 01-13-94 Schuler     Added SetMsgHook and SetBeepHook
  49. * 01-31-94 Schuler     Modified Message and _DefMessageHook (see below)
  50. * 02-07-94 Schuler     Added element to _sev_code[] array for SEV_NONE
  51. * ==========================================================================
  52. */
  53.  
  54. extern char * g_corelib;
  55. static char * this_file = __FILE__;
  56.  
  57. #undef  THIS_MODULE
  58. #define THIS_MODULE g_corelib
  59. #undef  THIS_FILE
  60. #define THIS_FILE this_file
  61.  
  62. #include <ncbi.h>
  63. #include <ncbiwin.h>
  64.  
  65. #ifdef DCLAP
  66. /* add back the undef from header */
  67. #define Monitor Nlm_Monitor
  68. #define MonitorPtr Nlm_MonitorPtr
  69. #endif
  70.  
  71. #ifdef VAR_ARGS
  72. #include <varargs.h>
  73. #define VSPRINTF(buff,fmt)         \
  74.     {                              \
  75.         va_list args;              \
  76.         va_start(args);            \
  77.         vsprintf(buff,fmt,args);   \
  78.         va_end(args);              \
  79.     }
  80.  
  81. #else
  82. #include <stdarg.h>
  83. #define VSPRINTF(buff,fmt)         \
  84.     {                              \
  85.         va_list args;              \
  86.         va_start(args,fmt);        \
  87.         vsprintf(buff,fmt,args);   \
  88.         va_end(args);              \
  89.     }
  90. #endif
  91.  
  92.  
  93. MsgAnswer PASCAL _DefMessageHook PROTO((MsgKey key, ErrSev sev,
  94.             const char *caption, const char *message));
  95.             
  96. void PASCAL _DefBeepHook PROTO((void));
  97.  
  98. int PASCAL _DefMonitorHook PROTO((MonitorPtr pMon, MonCode code));
  99.  
  100.  
  101. /*************************************************************************\
  102. |                    INSTANCE-SPECIFIC INFO STRUCTURE                     |
  103. \*************************************************************************/
  104.  
  105. typedef struct AppMsgInfo
  106. {
  107.     MessageHook hookMessage;
  108.     BeepHook hookBeep;
  109.     MonitorHook hookMonitor;
  110. }
  111. AppMsgInfo;
  112.  
  113. static char * _szPropKey = "_AppMsgInfo";
  114.  
  115. static AppMsgInfo * GetAppMsgInfo (void)
  116.  
  117. {
  118.     AppMsgInfo *info = (AppMsgInfo*) GetAppProperty(_szPropKey);
  119.     
  120.     if (info == NULL)
  121.     {
  122.         info = (AppMsgInfo*) MemGet(sizeof(struct AppMsgInfo), TRUE);
  123.         if (info == NULL)  AbnormalExit(1);  
  124.             
  125.         info->hookMessage = _DefMessageHook;
  126.         info->hookBeep = _DefBeepHook;
  127.         info->hookMonitor = _DefMonitorHook;
  128.         
  129.         SetAppProperty(_szPropKey,(void*)info);
  130.     }
  131.     return info;
  132. }
  133.  
  134.  
  135. /*************************************************************************\
  136. |                                ALERTS                                   |
  137. \*************************************************************************/
  138. #if defined(WIN_DUMB) || defined(OS_MAC)
  139. static int GetOneChar PROTO((void));
  140. #endif
  141.  
  142. #ifdef WIN_MSWIN
  143. char sProgramName[16];
  144. #endif
  145.  
  146. /*-------------------------------------------------------------------------
  147. * Message
  148. *
  149. *   Nlm_Message(key, format, ...)
  150. *       key = type of message
  151. *       MSG_ERROR 0 = non-fatal error
  152. *       MSG_FATAL 1 = fatal error
  153. *       MSG_OK    2 = OK
  154. *       MSG_RC    3 = Retry Cancel
  155. *       MSG_ARI   4 = Abort Retry Ignore
  156. *       MSG_YN    5 = Yes/No
  157. *       MSG_YNC   6 = Yes/No/Cancel
  158. *       MSG_OKC   7 = OK/Cancel
  159. *       MSG_POST  8 = show message, no response required
  160. *       MSG_POSTERR 9 = beep, show message, no response required
  161. *
  162. *   reply is:
  163. *       0 = no
  164. *       1 = yes or ok or retry
  165. *       abort/cancel
  166. *       3 = ignore
  167. *
  168. *       #define ANS_NO 0
  169. *       #define ANS_YES 1
  170. *       #define ANS_OK 1
  171. *       #define ANS_RETRY 1
  172. *       #define ANS_ABORT 2
  173. *       #define ANS_CANCEL 2
  174. *       #define ANS_IGNORE 3
  175. *
  176. *
  177. * MODIFICATIONS
  178. * 01-31-94 Schuler   Added calls to Beep() and AbnormalExit() where
  179. *                    appropriate instead of expecting the MessageHook
  180. *                    to do this.
  181. */
  182.  
  183. extern char *GetScratchBuffer PROTO((void));
  184.  
  185. #ifdef VAR_ARGS
  186. MsgAnswer CDECL Nlm_Message (sevkey, fmt, va_alist)
  187.     Nlm_Int2 sevkey;
  188.     const char *fmt;
  189.     va_dcl
  190. #else
  191. MsgAnswer CDECL Nlm_Message (Nlm_Int2 sevkey, const char *fmt, ...)
  192. #endif
  193. {
  194.     char *caption = (char*) GetAppProperty("ProgramName");
  195.     char *message = GetScratchBuffer();
  196.     MsgKey key = KEY_OK;
  197.     ErrSev sev = SEV_INFO;
  198.     MsgAnswer ans;
  199.  
  200.     if (sevkey < KEY_other)
  201.     {
  202.         key = (MsgKey) sevkey;
  203.         sev = SEV_INFO;
  204.     }
  205.     else 
  206.     {
  207.         key = KEY_OK;
  208.         sev = SEV_INFO;
  209.  
  210.         switch (sevkey)
  211.         {   
  212.             case MSG_ERROR :
  213.                 Nlm_Beep();
  214.                 sev = SEV_ERROR;
  215.                 break;
  216.             case MSG_FATAL :
  217.                 Nlm_Beep();
  218.                 sev = SEV_FATAL;
  219.                 break;
  220.             case MSG_POSTERR :
  221.                 Nlm_Beep();
  222.                 sev = SEV_ERROR;
  223.                 key = KEY_NONE;
  224.                 break;
  225.             case MSG_POST :
  226.                 key = KEY_NONE;
  227.                 break;
  228.         }
  229.     }
  230.     
  231.     VSPRINTF(message,fmt);
  232.     ans = MsgAlertStr(key,sev,caption,message);
  233.  
  234.     if (sevkey == MSG_FATAL)
  235.         AbnormalExit(1);
  236.  
  237.     return ans;
  238. }
  239.  
  240.  
  241. /*-------------------------------------------------------------------------
  242. * MsgAlert  [Schuler, 01-13-94]
  243. */
  244.  
  245. #ifdef VAR_ARGS
  246. MsgAnswer CDECL Nlm_MsgAlert (key, sev, caption, fmt, va_alist)
  247.     MsgKey key;
  248.     ErrSev sev;
  249.     const char *caption;
  250.     const char *fmt;
  251.     va_dcl
  252. #else
  253. MsgAnswer CDECL Nlm_MsgAlert (MsgKey key, ErrSev sev, const char *caption, const char *fmt, ...)
  254. #endif
  255. {
  256.     char *message = GetScratchBuffer();
  257.     VSPRINTF(message,fmt);
  258.     return MsgAlertStr(key,sev,caption,message);
  259. }
  260.  
  261.  
  262. /*-------------------------------------------------------------------------
  263. * MsgAlertStr  [Schuler, 01-13-94]
  264. */
  265. MsgAnswer LIBCALL Nlm_MsgAlertStr (MsgKey key, ErrSev sev, 
  266.             const char *caption, const char *message)
  267. {
  268.     MessageHook hook = GetAppMsgInfo()->hookMessage;
  269.     return (*hook)(key,sev,caption,message);
  270. }
  271.  
  272.  
  273. /*-------------------------------------------------------------------------
  274. * _DefMessageHook  [Schuler, 01-13-94, from the old Message]
  275. *
  276. * MODIFICATIONS:
  277. * 01-24-94 Schuler   Check for NULL message string
  278. * 01-31-94 Schuler   Removed Beep() and AbnormalExit() calls
  279. */
  280.  
  281. #ifdef WIN_MSWIN
  282. static UINT _sev_code[] = { 
  283.     /* SEV_NONE */    MB_OK,
  284.     /* SEV_INFO */    MB_ICONINFORMATION,
  285.     /* SEV_WARNING */ MB_ICONASTERISK, /* same as MB_ICONINFORMATION */
  286.     /* SEV_ERROR */   MB_ICONEXCLAMATION,
  287.     /* SEV_FATAL */   MB_ICONHAND };
  288. #endif
  289.  
  290. #if defined(WIN_DUMB) || defined(OS_MAC)
  291. static char * _key_str [] = { 
  292.     /* KEY_NONE */ "",
  293.     /* KEY_OK */   "Hit Return  ", 
  294.     /* KEY_OKC */  "C = Cancel, Anything else = OK  ",
  295.     /* KEY_ARI */  "A = abort, R = retry, I = ignore  ",
  296.     /* KEY_YNC */  "Y = yes, N = no, C = cancel  ",
  297.     /* KEY_YN */   "Y = yes, N = no  ",
  298.     /* KEY_RC */   "R = retry, C = Cancel  " };
  299. #endif
  300.  
  301.  
  302. MsgAnswer PASCAL _DefMessageHook (MsgKey key, ErrSev sev, 
  303.             const char *caption, const char *message)
  304. {
  305.     MsgAnswer answer = ANS_NONE;
  306.     
  307. #ifdef WIN_MSWIN
  308.     UINT flags = MB_TASKMODAL | _sev_code[(int)sev];
  309.     if (key > 0)  flags |= (key-1);                    
  310.     answer = MessageBox(NULL,message,caption,flags);
  311.     if (sev == SEV_FATAL)
  312.         AbnormalExit(1);
  313. #endif
  314.  
  315. #if defined(WIN_DUMB) || defined(OS_MAC)
  316.     fflush(stdout);
  317.     if (message != NULL)    
  318.         fprintf(stderr,"%s\n",message);
  319.     
  320.     if (key>KEY_NONE && key<KEY_other)
  321.     {
  322.         int ch;
  323.         
  324.         /* show prompt */        
  325.         fprintf(stderr,"%s  ",_key_str[(int)key]);    
  326.  
  327.         /* set default value */
  328.         switch (key)  
  329.         {
  330.             case KEY_OK :
  331.             case KEY_OKC :
  332.                 answer = ANS_OK;
  333.                 break;
  334.             case KEY_ARI :
  335.             case KEY_RC :
  336.                 answer = ANS_RETRY;
  337.                 break;
  338.             case KEY_YNC :
  339.             case KEY_YN :
  340.                 answer = ANS_YES;
  341.                 break;
  342.         }
  343.     
  344.         /* get response */
  345.         ch = GetOneChar();
  346.         ch = isalpha(key) ? toupper(ch) : ch;
  347.         switch (ch)
  348.         {
  349.             case 'A' :
  350.                 answer = ANS_ABORT;
  351.                 break;
  352.             case 'C' :
  353.                 answer = ANS_CANCEL;
  354.                 break;
  355.             case 'I' :
  356.                 answer = ANS_IGNORE;
  357.                 break;
  358.             case 'N' :
  359.                 answer = ANS_NO;
  360.                 break;
  361.         }
  362.     }
  363. #endif
  364.  
  365.     return answer;
  366. }
  367.  
  368. /*-------------------------------------------------------------------------
  369. * SetMessageHook  [Schuler, 01-13-94]
  370. */
  371. MessageHook LIBCALL Nlm_SetMessageHook (MessageHook hook)
  372. {
  373.     AppMsgInfo *info = GetAppMsgInfo();
  374.     MessageHook hookPrev = info->hookMessage;
  375.     if (hookPrev ==_DefMessageHook) hookPrev = NULL;
  376.     info->hookMessage = (hook == NULL) ? _DefMessageHook : hook;
  377.     return hookPrev;
  378. }
  379.  
  380. /*-------------------------------------------------------------------------
  381. * GetOneChar
  382. *
  383. * Gets a single character from the console
  384. *
  385. * MODIFICATIONS
  386. * 01-13-94 Schuler   Simplified (old version preserved below)
  387. */
  388. #if defined(WIN_DUMB) || defined(OS_MAC)
  389.  
  390. #if defined(COMP_MSC) || defined(COMP_BOR) || defined(COMP_SYMC)
  391. #include <conio.h>        // for getche prototype
  392. #endif
  393.  
  394. static int GetOneChar ()
  395. {
  396.     int value =0;
  397.  
  398. #if defined(COMP_MSC) || defined(COMP_BOR) || defined(COMP_SYMC)
  399.     value = getche();
  400.     putchar('\n');
  401. #else
  402.     int tvalue;
  403.     do
  404.     {
  405.         tvalue = getchar();
  406.         if (! value)
  407.             value = tvalue;
  408.     } while (tvalue != '\n');
  409. #endif
  410.     return value;
  411. }
  412. #endif
  413.  
  414.  
  415. /*************************************************************************\
  416. |                                 BEEPS                                   |
  417. \*************************************************************************/
  418.  
  419.  
  420. /*-------------------------------------------------------------------------
  421. * Beep
  422. *
  423. * MODIFICATIONS
  424. * 01-13-94 Schuler   Modified to use BeepHook (old version preserved below)
  425. */
  426.  
  427. void LIBCALL  Nlm_Beep ()
  428. {
  429.     BeepHook hook = GetAppMsgInfo()->hookBeep;
  430.     (*hook)();
  431. }
  432.  
  433.  
  434. /*-------------------------------------------------------------------------
  435. * _DefBeepHook  [Schuler, 01-13-94, from old Beep code]
  436. *
  437. * Default beep function
  438. */
  439. void LIBCALLBACK _DefBeepHook ()
  440. {
  441. #ifdef OS_MAC
  442.     SysBeep(60);
  443. #endif
  444. #ifdef WIN16
  445.     MessageBeep(0);
  446. #endif
  447. #if defined(WIN32) || defined(WIN32BOR)
  448.     Beep(60,10);
  449. #endif
  450. #ifdef WIN_DUMB
  451.     putc(7,stderr);
  452. #endif
  453. }
  454.  
  455. /*-------------------------------------------------------------------------
  456. * SetBeepHook  [Schuler, 01-13-94]
  457. */
  458. BeepHook LIBCALL Nlm_SetBeepHook (BeepHook hook)
  459. {
  460.     AppMsgInfo *info = GetAppMsgInfo();
  461.     BeepHook hookPrev = info->hookBeep;
  462.     if (hookPrev == (BeepHook)_DefBeepHook) hookPrev = NULL;
  463.     info->hookBeep = (hook == NULL) ? _DefBeepHook : hook;
  464.     return hookPrev;
  465. }
  466.  
  467. /*************************************************************************\
  468. |                            PROGRESS MONITORS                            |
  469. \*************************************************************************/
  470.  
  471. #define MON_MAGIC_VALUE        1234
  472.  
  473. /*
  474. #define MON_SET_MAGIC(x)    (x)->magic_value = MON_MAGIC_VALUE
  475. #define MON_IS_VALID(x)        ((x)!=NULL  && (x)->magic_value==MON_MAGIC_VALUE)
  476. */
  477. #define MON_MAGIC(x)       *((int*)((char*)(x) + sizeof(Monitor)))
  478. #define MON_SET_MAGIC(x)   MON_MAGIC(x) = MON_MAGIC_VALUE
  479. #define MON_IS_VALID(x)    (MON_MAGIC(x) == MON_MAGIC_VALUE)
  480.  
  481.  
  482. /*-------------------------------------------------------------------------
  483. * MonitorIntNew
  484. *
  485. * Creates an integer range monitor
  486. *
  487. * MODIFICATIONS
  488. * 05-27-93 Schuler   Support for applications hooking into monitors
  489. * 06-03-93 Schuler   Use of magic number to detect invalid pointers
  490. */
  491.  
  492. MonitorPtr LIBCALL Nlm_MonitorIntNew (Nlm_CharPtr title, Nlm_Int4 n1, Nlm_Int4 n2)
  493. {
  494.     AppMsgInfo *info = GetAppMsgInfo();
  495.     Nlm_sizeT bytes = sizeof(Monitor) + sizeof(int);
  496.     Monitor *pMon = (Monitor*) MemNew(bytes);
  497.  
  498.     if (pMon != NULL)
  499.     {
  500.         MON_SET_MAGIC(pMon);
  501.         pMon->type = MonType_Int;
  502.         pMon->strTitle = title ? StrSave(title) : NULL;
  503.         pMon->num1 = n1;
  504.         pMon->num2 = n2;
  505.         if (!(*info->hookMonitor)(pMon,MonCode_Create))
  506.         {
  507.             MonitorFree(pMon);
  508.             /* only post an information message here; it is expected
  509.                 that the hook function would report the real reason
  510.                 that the monitor creation failed. */
  511.             ErrPostEx(SEV_INFO,0,0,"Unable to create monitor");
  512.             return NULL;
  513.         }
  514.     }
  515.     return pMon;
  516. }
  517.  
  518.  
  519. /** TO DO:  define error codes for these conditions **/
  520. static char * _invalid_mon = "invalid monitor pointer";
  521. static char * _invalid_type = "invalid monitor type";
  522.  
  523. /*-------------------------------------------------------------------------
  524. * MonitorStrNew
  525. *
  526. * Creates a string monitor.  The len argument is the maximum string length.
  527. *
  528. * MODIFICATIONS
  529. * 05-27-93 Schuler   Support for applications hooking into monitors
  530. * 06-03-93 Schuler   Use of magic number to detect invalid pointers
  531. */
  532.  
  533. MonitorPtr LIBCALL Nlm_MonitorStrNew (Nlm_CharPtr title, Nlm_Int2 len)
  534. {
  535.     AppMsgInfo *info = GetAppMsgInfo();
  536.     Nlm_sizeT bytes = sizeof(Monitor) + sizeof(short);
  537.     Monitor *pMon = (Monitor*) MemNew(bytes);
  538.  
  539.     if (pMon != NULL)
  540.     {
  541.         MON_SET_MAGIC(pMon);
  542.         pMon->type = MonType_Str;
  543.         pMon->strTitle = title ? StrSave(title) : NULL;
  544.         pMon->num1 = MAX(0,MIN(len,72));
  545.         (*info->hookMonitor)(pMon,MonCode_Create);
  546.     }
  547.     return pMon;
  548. }
  549.  
  550.  
  551. /*-------------------------------------------------------------------------
  552. * MonitorStrValue
  553. *
  554. * Sets the string value for a string monitor.
  555. *
  556. * MODIFICATIONS
  557. * 05-27-93 Schuler   Support for applications hooking into monitors
  558. * 06-03-93 Schuler   Use of magic number to detect invalid pointers
  559. * 06-03-93 Schuler   Check that monitor is correct type (MonType_Str)
  560. */
  561.  
  562. Nlm_Boolean LIBCALL Nlm_MonitorStrValue (MonitorPtr pMon, Nlm_CharPtr sval)
  563. {
  564.     AppMsgInfo *info = GetAppMsgInfo();
  565.     if ( ! MON_IS_VALID(pMon) )
  566.     {
  567.         ErrPostEx(SEV_WARNING,0,0,"MonitorStrValue: %s",_invalid_mon);
  568.         return FALSE;
  569.     }
  570.     if (pMon->type != MonType_Str)
  571.     {
  572.         ErrPostEx(SEV_WARNING,0,0,"MonitorStrValue: %s",_invalid_type);
  573.         return FALSE;
  574.     }
  575.  
  576.     if (pMon->strValue) MemFree((void*)pMon->strValue);
  577.     pMon->strValue = sval ? StrSave(sval) : NULL;
  578.     (*info->hookMonitor)(pMon,MonCode_StrValue);
  579.     return TRUE;
  580. }
  581.  
  582.  
  583. /*-------------------------------------------------------------------------
  584. * MonitorIntValue
  585. *
  586. * Sets the integer value for an integer range monitor
  587. *
  588. * MODIFICATIONS
  589. * 05-27-93 Schuler   Support for applications hooking into monitors
  590. * 06-03-93 Schuler   Use of magic number to detect invalid pointers
  591. * 06-03-93 Schuler   Check that monitor is correct type (MonType_Int)
  592. */
  593.  
  594. Nlm_Boolean LIBCALL Nlm_MonitorIntValue (MonitorPtr pMon, Nlm_Int4 ival)
  595. {
  596.     AppMsgInfo *info = GetAppMsgInfo();
  597.     if ( !MON_IS_VALID(pMon) )
  598.     {
  599.         ErrPostEx(SEV_WARNING,0,0,"MonitorIntValue: %s",_invalid_mon);
  600.         return FALSE;
  601.     }
  602.     if (pMon->type != MonType_Int)
  603.     {
  604.         ErrPostEx(SEV_WARNING,0,0,"MonitorStrValue: %s",_invalid_type);
  605.         return FALSE;
  606.     }
  607.  
  608.     pMon->intValue = ival;
  609.     (*info->hookMonitor)(pMon,MonCode_IntValue);
  610.     return TRUE;
  611. }
  612.  
  613.  
  614. /*-------------------------------------------------------------------------
  615. * MonitorFree
  616. *
  617. * MODIFICATIONS
  618. * 05-27-93 Schuler   Support for applications hooking into monitors
  619. * 06-03-93 Schuler   Use of magic number to detect invalid pointers
  620. */
  621.  
  622. MonitorPtr LIBCALL Nlm_MonitorFree (MonitorPtr pMon)
  623. {
  624.     AppMsgInfo *info = GetAppMsgInfo();
  625.     if ( ! MON_IS_VALID(pMon) )
  626.     {
  627.         ErrPostEx(SEV_WARNING,0,0,"MonitorFree: %s",_invalid_mon);
  628.     }
  629.     else
  630.     {
  631.         (*info->hookMonitor)(pMon,MonCode_Destroy);
  632.         MemFree((void*)pMon->strTitle);
  633.         MemFree((void*)pMon->strValue);
  634.         MemFree(pMon);
  635.     }
  636.     return NULL;
  637. }
  638.  
  639.  
  640. /*-------------------------------------------------------------------------
  641. * SetMonitorHook    [Schuler, 05-27-93]
  642. *
  643. * Allows the application to set a hook procedure that will be called
  644. * when a monitor is created, destroyed, or changes value.
  645. *
  646. * MODIFICATIONS
  647. * 01-13-94 Schuler   No longer allows you to set the hook to NULL.
  648. */
  649.  
  650. MonitorHook LIBCALL Nlm_SetMonitorHook (MonitorHook hook)
  651. {
  652.     AppMsgInfo *info = GetAppMsgInfo();
  653.     MonitorHook hookPrev = info->hookMonitor;
  654.     if (hookPrev ==_DefMonitorHook) hookPrev = NULL;
  655.     info->hookMonitor = (hook == NULL) ? _DefMonitorHook : hook;
  656.     return hookPrev;
  657. }
  658.  
  659.  
  660.  
  661. /*-------------------------------------------------------------------------
  662. *    _DefMonitorHook    [Schuler, 05-27-93]
  663. *
  664. *    IMPORTANT:  If your program is NOT a console-style (WIN_DUMB), you
  665. *    should either (1) use Vibrant or (2) write a monitor hook function
  666. *    and install it with SetMonitorHook.  Otherwise, the following
  667. *    "do-nothing" function will be used and you will not see anything.
  668. */
  669.  
  670. #ifndef WIN_DUMB
  671.  
  672. int PASCAL _DefMonitorHook (MonitorPtr pMon, MonCode code)
  673. {
  674.     switch (code)
  675.     {
  676.         case MonCode_Create :
  677.             TRACE("[%s]\n",pMon->strTitle);
  678.             return TRUE;
  679.         case MonCode_StrValue :
  680.             TRACE("%s\n",pMon->strValue);
  681.             break;
  682.     }
  683.     return 0;
  684. }
  685.  
  686. #else  /* WIN_DUMB */
  687.  
  688. static int  Dumb_MonCreate PROTO((MonitorPtr pMon));
  689. static void Dumb_MonDestroy PROTO((MonitorPtr pMon));
  690. static void Dumb_MonIntValue PROTO((MonitorPtr pMon));
  691. static void Dumb_MonStrValue PROTO((MonitorPtr pMon));
  692.  
  693.  
  694.  
  695. int PASCAL _DefMonitorHook (MonitorPtr pMon, MonCode code)
  696. {
  697.     switch (code)
  698.     {
  699.         case MonCode_Create :
  700.             return Dumb_MonCreate(pMon);
  701.             break;
  702.         case MonCode_Destroy :
  703.             Dumb_MonDestroy(pMon);
  704.             break;
  705.         case MonCode_IntValue :
  706.             Dumb_MonIntValue(pMon);
  707.             break;
  708.         case MonCode_StrValue :
  709.             Dumb_MonStrValue(pMon);
  710.             break;
  711.     }
  712.     return 0;
  713. }
  714.  
  715. static int Dumb_MonCreate (MonitorPtr pMon)
  716. {
  717.     char *buf;
  718.  
  719.     if ((buf = Nlm_Calloc(81,1)) == NULL)
  720.         return FALSE;
  721.     buf[80] = '\0';
  722.     pMon->extra = buf;
  723.  
  724.     fprintf(stderr, "\n\n<<< %s >>>\n", pMon->strTitle);
  725.  
  726.     if (pMon->type == MonType_Int)
  727.     {
  728.         fprintf(stderr, "<-%-8ld--------------------%8ld->\n",pMon->num1,pMon->num2);
  729.     }
  730.     else
  731.     {
  732.         Nlm_sizeT len = (Nlm_sizeT) pMon->num1;
  733.  
  734.         MemSet(buf, '<', 3);
  735.         MemSet(&buf[3], ' ', len+2);
  736.         MemSet(&buf[len+5], '>', 3);
  737.         buf[80] = '\0';
  738.         fprintf(stderr, "%s", buf);
  739.     }
  740.  
  741.     fflush(stderr);
  742.     return TRUE;
  743. }
  744.  
  745. static void Dumb_MonDestroy (MonitorPtr pMon)
  746. {
  747.     MemFree(pMon->extra);
  748.     fprintf(stderr, "\n\n");
  749.     fflush(stderr);
  750. }
  751.  
  752. static void Dumb_MonIntValue (MonitorPtr pMon)
  753. {
  754.     char *buf = pMon->extra;
  755.     long value = pMon->intValue;
  756.     long range = ABS(pMon->num2 - pMon->num1);
  757.     Nlm_sizeT diff = 0;
  758.     int bRefresh = FALSE;
  759.  
  760.     if (range ==0)  return;  /* watch out for divide-by-zero! */
  761.  
  762.     if (pMon->num2 >= pMon->num1)
  763.     {
  764.         if (value > pMon->num1)
  765.         {
  766.             if (value >= pMon->num2)
  767.                 diff = 40;
  768.             else
  769.                 diff = (Nlm_sizeT) (((value - pMon->num1) * 40) / range);
  770.  
  771.             if (diff==0 || diff==40 || buf[diff-1] != '#' || buf[diff] != ' ')
  772.             {
  773.                 MemSet(&buf[0], '#', diff);
  774.                 MemSet(&buf[diff], ' ', 40-diff);
  775.                 bRefresh = TRUE;
  776.             }
  777.         }
  778.     }
  779.     else
  780.     {
  781.         if (value < pMon->num1)
  782.         {
  783.             if (value <= pMon->num2)
  784.                 diff = 40;
  785.             else
  786.                 diff = (Nlm_sizeT) (((value - pMon->num2) * 40) / range);
  787.  
  788.             if (diff==0 || diff==40 || buf[40-diff] != '#' || buf[40-diff-1] != ' ')
  789.             {
  790.                 MemSet(&buf[40 - diff],'#',diff);
  791.                 MemSet(&buf[0], ' ', 40-diff);
  792.                 bRefresh = TRUE;
  793.             }
  794.         }
  795.     }
  796.     if (bRefresh)
  797.     {
  798.         fprintf(stderr, "\r%s", buf);
  799.         fflush(stderr);
  800.     }
  801. }
  802.  
  803. static void Dumb_MonStrValue (MonitorPtr pMon)
  804. {
  805.     char *buf = (char *) pMon->extra;
  806.     Nlm_sizeT len0 = (int)pMon->num1;
  807.     Nlm_sizeT len1 = MIN(StringLen(pMon->strValue),len0);
  808.     Nlm_sizeT diff = (len0-len1)/2;
  809.     Nlm_MemFill(&buf[3],' ',len0+2);
  810.     Nlm_MemCopy(&buf[4+diff],pMon->strValue,len1);
  811.     fprintf(stderr,"\r%s",buf);
  812.     fflush(stderr);
  813. }
  814.  
  815. #endif  /* WIN_DUMB */
  816.  
  817. /*****************************************************************************
  818. *
  819. *   Default Monitor
  820. *      This will be moved to ncbimsg soon !!!!
  821. *
  822. *****************************************************************************/
  823.  
  824.  
  825. static Nlm_VoidPtr stdmondata = NULL;
  826. static Nlm_ProgMonFunc stdmonfunc = NULL;
  827.  
  828. /*****************************************************************************
  829. *
  830. *   ProgMon(str)
  831. *       Default progress monitor
  832. *
  833. *****************************************************************************/
  834. Nlm_Boolean LIBCALL Nlm_ProgMon(Nlm_CharPtr str)
  835. {
  836.     Nlm_Boolean retval;
  837.  
  838.     if (stdmonfunc == NULL)
  839.         return TRUE;
  840.  
  841.     retval = (* stdmonfunc)(stdmondata, str);
  842.     
  843.     return retval;
  844. }
  845.  
  846.  
  847. /*****************************************************************************
  848. *
  849. *   SetProgMon(func, data)
  850. *
  851. *****************************************************************************/
  852. Nlm_Boolean LIBCALL Nlm_SetProgMon (ProgMonFunc func, Nlm_VoidPtr data)
  853. {
  854.     stdmonfunc = func;
  855.     stdmondata = data;
  856.     return TRUE;
  857. }
  858.  
  859.  
  860. /*****************************************************************************
  861. *
  862. *   StdProgMon(data, str)
  863. *
  864. *****************************************************************************/
  865. Nlm_Boolean LIBCALLBACK Nlm_StdProgMon(Nlm_VoidPtr data, Nlm_CharPtr str)
  866. {
  867.     return Nlm_MonitorStrValue((Nlm_MonitorPtr) data, str);
  868. }
  869.  
  870.